package com.dldata.devtools30.utils;

//import com.sun.imageio.plugins.jpeg.JPEGImageWriter;
//import com.sun.imageio.plugins.png.PNGImageWriter;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.plugins.jpeg.JPEGImageWriteParam;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.sql.Timestamp;
import java.util.Date;

/**
 *
 * 我们现在的逻辑是: 1.按比例压缩,最小边是320,强制转换成jpg 2.发现超过100K的再做压缩质量调整.让他小于100K. 3.写入磁盘
 *
 * 读入文件 目前只支持文件内容格式为png,bmp,gif,jpeg,x-png,vnd.wap.wbmp
 */
public class PicturreUtil {

    /**
     * Logo 文件的大小 kb单位
     */
    private static final int LogoSize = 100;

    /**
     * LogoWidth 图片的宽度或者高度最小为多大 px单位
     */
    private static final int LogoWidth = 320;

    private static final Logger logger =  LoggerFactory.getLogger(PicturreUtil.class);

    /**
     * 0.读入内存 1.按比例压缩,最小边是320,强制转换成jpg 2.发现超过100K的再做压缩质量调整.让他小于100K. 3.写入磁盘
     *
     * @param fileName
     * @return
     */
    public static boolean operateImage(String fileName,Integer maxDim,String destFileName) {

        return operateImage(fileName, maxDim, destFileName, LogoSize);
    }

    public static boolean operateImage(String fileName, Integer maxDim, String destFileName,int maxLogoSize) {
        File imgFile = null;
        ByteArrayOutputStream dImg = null;

        try {
            // 内存划二块
            imgFile = new File(fileName);
            dImg = new ByteArrayOutputStream();

            // 把文件读到内存
            boolean resRead = ReadFromFile(imgFile, dImg);
            logger.info("ReadFromFile: "+resRead);
            if (!resRead)
                return false;

            // 1.[转换格式JPG&&大小调整]按比例压缩,最小边是320
            maxDim=(maxDim==null||maxDim==0)?LogoWidth:maxDim;
            boolean reImg = resizeImage(maxDim, dImg);
            logger.info("resizeImage: "+reImg);
            if (!reImg)
                return false;

            // 2.[质量调整 jpg]发现超过100K的再做转换.让他小于100K.
            String suffix=destFileName.lastIndexOf(".")!=-1?destFileName.substring(destFileName.lastIndexOf(".")+1):"jpg";
            boolean reRate = chCommRate(dImg,suffix,maxLogoSize);
            if (!reRate)
                return false;

            // 3.把转换成功的内存img写入磁盘
            boolean reWrite = WriteToFile(dImg, destFileName,suffix);
            if (!reWrite)
                return false;

        } finally {
            imgFile = null;
            try {
                if (dImg != null)
                    dImg.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return true;
    }

    /**
     * 更改图像的压缩质量，直到小于LogoSize 或者质量小于30
     *
     * @param byteos
     * @return
     */
    public static boolean chCommRate(ByteArrayOutputStream byteos,String suffix,int maxLogoSize) {
        boolean result = true;
        int quality = 100;
        try {

            BufferedImage sImg = ImageIO.read(new ByteArrayInputStream(byteos.toByteArray()));
            logger.info("byteos.size: "+byteos.size());

            while (byteos.size() / 1000 >= maxLogoSize && quality >= 20) {
                byteos.reset();

                // 设置压缩参数
                if(!"png".equals(suffix)){
                    ImageWriter imageWriter = (ImageWriter) ImageIO
                            .getImageWritersBySuffix("jpg").next();
                    imageWriter.setOutput(byteos);
                    JPEGImageWriteParam jpegParams = (JPEGImageWriteParam) imageWriter
                            .getDefaultWriteParam();
                    jpegParams.setCompressionMode(JPEGImageWriteParam.MODE_EXPLICIT);
                    jpegParams.setCompressionQuality(quality/100F);

                    imageWriter.write(sImg);
                    imageWriter.dispose();
                }else{
                    ImageWriter pngImageWriter=(ImageWriter)ImageIO
                            .getImageWritersBySuffix("png").next();;
                    pngImageWriter.setOutput(byteos);
                    ImageWriteParam imageWriteParam= pngImageWriter.getDefaultWriteParam();
                    imageWriteParam.setCompressionQuality(quality/100F);

                    pngImageWriter.write(sImg);
                    pngImageWriter.dispose();
                }
                logger.info("byteos.size: "+byteos.size());
                quality = quality - 10 >= 20 ? quality - 10 : 20;
            }
        } catch (Exception e) {
            result = false;
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 将缓存流 写入文件 JPG
     *
     * @param byteos
     * @param filename
     * @return
     */
    public static boolean WriteToFile(ByteArrayOutputStream byteos,
                                      String filename,String suffix) {
        boolean result = true;

        try {
//            ByteArrayInputStream byteInput = new ByteArrayInputStream(byteos
//                    .toByteArray());
//            BufferedImage sImg = ImageIO.read(new ByteArrayInputStream(byteos.toByteArray()));
//            ImageIO.write(sImg, suffix, new File(filename));
//            byteInput.close();
            FileUtils.writeByteArrayToFile(new File(filename), byteos
                    .toByteArray(), false);
        } catch (Exception e) {
            result = false;
            e.printStackTrace();
        }

        return result;
    }

    /**
     * 读文件文件 并输出到ByteArrayOutputStream 失败就返回错误
     *
     * @param imgFile
     * @param ous
     * @return
     */
    public static boolean ReadFromFile(File imgFile, ByteArrayOutputStream ous) {
        boolean res = true;
        InputStream in = null;
        try {
            in = new FileInputStream(imgFile);
            ImageIO.write(ImageIO.read(in), "jpg", ous);
        } catch (Exception e) {
            logger.info(e.getMessage());
            res = false;
        } finally {
            try {
                in.close();
            } catch (Exception e) {
            }
        }

        return res;
    }

    /**
     * 把源图片pSoImg按照最小边maxDim等比例缩小 并转换成JPG 写入OutStream
     *
     * @param maxDim
     * @param OutStream
     * @return
     */
    public static boolean resizeImage(int maxDim,
                                      ByteArrayOutputStream OutStream) {
        // sFileName,tFileName 内存imgFile
        boolean resultImg = true;

        try {
            BufferedImage sImg = ImageIO.read(new ByteArrayInputStream(OutStream.toByteArray()));

            // 得到图片的大小
            int imh = sImg.getHeight();
            int imw = sImg.getWidth();
//            int imMin = imh < imw ? imh : imw;
//            int imMax = imh > imw ? imh : imw;
            int scaledW = imw;
            int scaledH = imh;

            //最大边也小于maxDim不动
            if(imw<maxDim){
                return true;
            }

            // 最小边大于maxDim 并按比例缩小
            if (imw > maxDim) {
                double scale = (double) maxDim / (double) imw;
                scaledW = (int) (scale * imw);
                scaledH = (int) (scale * imh);
            }

            Image tempImg = Toolkit.getDefaultToolkit().createImage(
                    sImg.getSource()).getScaledInstance(scaledW,
                    scaledH, Image.SCALE_SMOOTH);
            OutStream.reset();
            BufferedImage outputImage = new BufferedImage(scaledW, scaledH,BufferedImage.TYPE_INT_RGB);
            Graphics graphics = outputImage.getGraphics();
            graphics.drawImage(tempImg, 0, 0, null);
            graphics.dispose();
            ImageIO.write(outputImage, "jpg", OutStream);
        } catch (Exception e) {
            resultImg = false;
            e.printStackTrace();
        }

        return resultImg;
    }

    public static void main(String[] args) throws IOException {

        String url = "http://dianxin.qingdaonews.com/img/2003-03/08/Wb0308080J.JPG";
        String tfullName = "D:/test/" + url.substring(url.lastIndexOf("/") + 1);

        tfullName = "C:\\Users\\呵呵\\Desktop\\32a1a18f7e38b3f10a05fe2e9d2250fc_200_200.png";
       String  tfullNameDest = "C:\\Users\\呵呵\\Desktop\\32a1a18f7e38b3f10a05fe2e9d2250fc_p1.png";
        // File f = new File(tfullName);
        // if (!f.exists()) {
        // f.createNewFile();
        // }
        // CommUtil.downFile(url,tfullName);
        // tfullName = "D:/test/24.bmp";
        // tfullName = "D:/test/24.jpg";
        // File f = new File(tfullName);
        // if (!f.exists()) {
        // f.createNewFile();
        // }
        // System.out.println(convertToPic(tfullName));
        // System.out.println(convertToPic2(fullName));
        System.out.println(operateImage(tfullName, 200, tfullNameDest, 28));
        String readFormats[] = ImageIO.getReaderMIMETypes();
        String writeFormats[] = ImageIO.getWriterMIMETypes();
//        System.out.println("Readers: " + Arrays.asList(readFormats) + ":"
//                + Arrays.asList(Jimi.getDecoderTypes()));
//        System.out.println("Writers: " + Arrays.asList(writeFormats) + ":"
//                + Arrays.asList(Jimi.getEncoderTypes()));
        Timestamp t = new Timestamp(new Date().getTime());
        System.out.println(t);
    }
}
